package us.mmapp;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import us.mmapp.util.HttpManager;
import us.mmapp.util.ServicesUtils;
import us.mmapp.util.TextUtils;
import us.mmapp.util.UIUtils;
import android.app.ProgressDialog;
import android.app.TabActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TabHost.TabContentFactory;
import android.widget.TextView;

public class FriendsActivity extends TabActivity implements OnTabChangeListener
{
	private static final String FRIENDS_TAB_TAG = "Friends";
	private static final String PENDING_TAB_TAG = "Pending";
	private static final String AWAITING_TAB_TAG = "Awaiting";
	
	private ListView listFriends;
	private ListView listPending;
	private ListView listAwaiting;
	private TabHost tabHost;
	
	private ProgressDialog mProgress;
	private ArrayList<Friend> mFriends;
	private ArrayList<Friend> mPending;
	private ArrayList<Friend> mAwaiting;
	
	private String mUserName;
	private String mPassword;
	
	@Override
	public void onCreate(Bundle savedInstaneState)
	{
		super.onCreate(savedInstaneState);
		// Check if is logged in
		SharedPreferences settings = getSharedPreferences("LOGIN", 0);
		boolean isLoggedIn = settings.getBoolean("loggedIn", false);

		if (!isLoggedIn)
		{
			startActivity(new Intent(this, LoginActivity.class));
			return;
		}
		mUserName = settings.getString("username", "");
		mPassword = settings.getString("password", "");
		
		setContentView(R.layout.friends_view);
		
		tabHost = getTabHost();
		tabHost.setOnTabChangedListener(this);
		
		// setup Friends
		listFriends = (ListView) findViewById(R.id.listFriends);
		listPending = (ListView) findViewById(R.id.listPending);
		listAwaiting = (ListView) findViewById(R.id.listAwaiting);
		tabHost.addTab(tabHost
				.newTabSpec(this.FRIENDS_TAB_TAG)
				.setIndicator(FRIENDS_TAB_TAG)
				.setContent(new TabContentFactory() {
					public View createTabContent(String arg0)
					{
						return listFriends;
					}
				}));
		tabHost.addTab(tabHost
				.newTabSpec(this.PENDING_TAB_TAG)
				.setIndicator(PENDING_TAB_TAG)
				.setContent(new TabContentFactory() {
					public View createTabContent(String arg0)
					{
						return listPending;
					}
				}));
		tabHost.addTab(tabHost
				.newTabSpec(this.AWAITING_TAB_TAG)
				.setIndicator(AWAITING_TAB_TAG)
				.setContent(new TabContentFactory() {
					public View createTabContent(String arg0)
					{
						return listAwaiting;
					}
				}));
		
		doFetchAll(false);
		tabHost.setCurrentTab(0);
	}


	public void onTabChanged(String tabId)
	{
		listFriends.setVisibility(View.GONE);
		listPending.setVisibility(View.GONE);
		listAwaiting.setVisibility(View.GONE);
		if (tabId.equals(FRIENDS_TAB_TAG))
		{
			listFriends.setVisibility(View.VISIBLE);
		}
		if (tabId.equals(PENDING_TAB_TAG))
		{
			listPending.setVisibility(View.VISIBLE);
		}
		if (tabId.equals(AWAITING_TAB_TAG))
		{
			listAwaiting.setVisibility(View.VISIBLE);
		}
	}
	public void doFetchAll(View v)
	{
		//delegate
		doFetchAll(false);
	}
	/**
	 * Fetch all friends.
	 */
	private void doFetchAll(final boolean silent)
	{
		// Create the progressDialog
		if (!silent)
		{
			mProgress = new ProgressDialog(this);
			mProgress.setMessage("Refreshing...");
			mProgress.setIndeterminate(true);
			mProgress.setCancelable(false);
			// Show the progress while doing the work
			mProgress.show();
		}
		//parameters, the progress values, and the final value of the task,
		AsyncTask<String, Void, JSONArray> t = new AsyncTask<String, Void, JSONArray>() {
			@Override
			protected JSONArray doInBackground(String... args) {
		    	JSONArray ret = null;
				try
				{
			    	HttpGet get = new HttpGet(ServicesUtils.GET_FRIENDS);
			    	
			    	get.addHeader(BasicScheme.authenticate(
			    			new UsernamePasswordCredentials(args[0],TextUtils.md5(args[1])),
			    			"UTF-8",
			    			false));
			    	
			    	HttpResponse httpResponse = HttpManager.execute(get);
			    	HttpEntity responseEntity = httpResponse.getEntity();
			    	
	                if (responseEntity != null)
	                {
                        InputStream instream = responseEntity.getContent();
                        String result = TextUtils.convertStreamToString(instream);           
                        instream.close();
                        // Try converting result to JSON
                        Log.e("FRIENDS", "Result: " + httpResponse);
                        try {
							ret = new JSONArray(result);
						} catch (JSONException e) {
							Log.e("FRIENDS", "Could not parse JSON.");
							ret = null;
						}
	                }
	                else
	                {
	                	Log.e("FRIENDS", "Response Entity Null.");
	                }
				}
				catch (IOException e)
				{}
		    	
				return ret;
			}
			@Override
			protected void onPostExecute(JSONArray result)
			{
				mFriends = new ArrayList<Friend>();
				mPending = new ArrayList<Friend>();
				mAwaiting = new ArrayList<Friend>();
				if (result == null)
				{
					// result null
				}
				else
				{
					
					for (int i = 0; i < result.length(); ++i)
					{
						try
						{
							Friend friend = new Friend(result.getJSONObject(i));
							switch (friend.status)
							{
							case 1:
								mFriends.add(friend);
								break;
							case 2:
								mPending.add(friend);
								break;
							case 3:
								mAwaiting.add(friend);
								break;
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					
				}
				// Put them all back as adapters
				adaptLists();
				if (!silent)
					mProgress.dismiss();
			}				
		};
		// Args needed for the working thread.
		String[] args = { mUserName, mPassword};
		t.execute(args);
	}
	@SuppressWarnings("unchecked")
	private void adaptLists()
	{
		listFriends.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mFriends)
		{
			@Override
			public View getView(int position, View convertView, ViewGroup parent)
			{
				   TextView label = (TextView)convertView;
				   if (convertView == null)
				   {
					  LayoutInflater inflater = getLayoutInflater();
			          convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
				      //convertView = new TextView(getContext());
				      label = (TextView)convertView;
				   }
				   label.setText(((Friend)this.getItem(position)).username);
				   return (convertView);
				}

		});
		
		listPending.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mPending)
		{
			@Override
			public View getView(int position, View convertView, ViewGroup parent)
			{
				   TextView label = (TextView)convertView;
				   if (convertView == null)
				   {
					  LayoutInflater inflater = getLayoutInflater();
			          convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
				      //convertView = new TextView(getContext());
				      label = (TextView)convertView;
				   }
				   label.setText(((Friend)this.getItem(position)).username);
				   return (convertView);
				}

		});
		listAwaiting.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, mAwaiting)
		{
			@Override
			public View getView(final int position, View convertView, ViewGroup parent)
			{
				   TextView label = (TextView)convertView;
				   if (convertView == null)
				   {
					  LayoutInflater inflater = getLayoutInflater();
			          convertView = inflater.inflate(android.R.layout.simple_list_item_1, null);
				      //convertView = new TextView(getContext());
				      label = (TextView)convertView;
				   }
				   label.setText(((Friend)this.getItem(position)).username);
				   convertView.setOnClickListener(new OnClickListener() {
				   final Friend f = mAwaiting.get(position);
					public void onClick(View v)
					{
						acceptFriend(f);
					}
				});
				   return (convertView);
				}

		});
		
		listFriends.invalidate();
		listAwaiting.invalidate();
		listPending.invalidate();
	}
	public void acceptFriend(final Friend who)
	{
		// Create the progressDialog
		mProgress = new ProgressDialog(this);
		mProgress.setMessage("Accepting Friend...");
		mProgress.setIndeterminate(true);
		mProgress.setCancelable(false);
		// Show the progress while doing the work
		mProgress.show();
		
		//parameters, the progress values, and the final value of the task,
		AsyncTask<String, Void, JSONObject> t = new AsyncTask<String, Void, JSONObject>() {
			@Override
			protected JSONObject doInBackground(String... args) {
		    	JSONObject ret = null;
				try
				{
					
			    	HttpPost post = new HttpPost(ServicesUtils.ACCEPT_FRIEND);
			    	
			    	// Add your data  
			    	List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);  
			    	nameValuePairs.add(new BasicNameValuePair("who_id", who.uid + ""));  
			    	post.setEntity(new UrlEncodedFormEntity(nameValuePairs));  
			    	
			    	post.addHeader(BasicScheme.authenticate(
			    			new UsernamePasswordCredentials(args[0],TextUtils.md5(args[1])),
			    			"UTF-8",
			    			false));
			    	
			    	
			    	HttpResponse httpResponse = HttpManager.execute(post);
			    	HttpEntity responseEntity = httpResponse.getEntity();
			    	
	                if (responseEntity != null)
	                {
                        InputStream instream = responseEntity.getContent();
                        String result = TextUtils.convertStreamToString(instream);           
                        instream.close();
                        // Try converting result to JSON
                        Log.e("FRIENDS", "Result: " + httpResponse);
                        try {
							ret = new JSONObject(result);
						} catch (JSONException e) {
							Log.e("FRIENDS", "Could not parse JSON.");
							ret = null;
						}
	                }
	                else
	                {
	                	Log.e("FRIENDS", "Response Entity Null.");
	                }
				}
				catch (IOException e)
				{}
		    	
				return ret;
			}
			@Override
			protected void onPostExecute(JSONObject result)
			{
				String msg = "Error occured.";		
				if (result != null)
				{
					String err;
					try
					{
						err = result.getString("error");
						msg = err;
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					try {
						err = result.getString("response");
						msg = err;
						// it was succesful
						mAwaiting.remove(who);
						mFriends.add(who);
						listAwaiting.invalidate();
						listFriends.invalidate();
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				// Put them all back as adapters
				//adaptLists();
				displayMessage(msg);
				mProgress.dismiss();
			}				
		};
		// Args needed for the working thread.
		String[] args = { mUserName, mPassword};
		t.execute(args);
	}
	public void addFriend(View v)
	{
		// Create the progressDialog
		mProgress = new ProgressDialog(this);
		mProgress.setMessage("Adding Friend...");
		mProgress.setIndeterminate(true);
		mProgress.setCancelable(false);
		// Show the progress while doing the work
		mProgress.show();
		
		//parameters, the progress values, and the final value of the task,
		AsyncTask<String, Void, JSONObject> t = new AsyncTask<String, Void, JSONObject>() {
			@Override
			protected JSONObject doInBackground(String... args) {
		    	JSONObject ret = null;
		    	EditText et = (EditText) findViewById(R.id.whoUsername);
				try
				{
					
			    	HttpPost post = new HttpPost(ServicesUtils.ADD_FRIEND);
			    	
			    	// Add your data  
			    	List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);  
			    	nameValuePairs.add(new BasicNameValuePair("who", et.getText().toString()));  
			    	post.setEntity(new UrlEncodedFormEntity(nameValuePairs));  
			    	
			    	post.addHeader(BasicScheme.authenticate(
			    			new UsernamePasswordCredentials(args[0],TextUtils.md5(args[1])),
			    			"UTF-8",
			    			false));
			    	
			    	
			    	HttpResponse httpResponse = HttpManager.execute(post);
			    	HttpEntity responseEntity = httpResponse.getEntity();
			    	
	                if (responseEntity != null)
	                {
                        InputStream instream = responseEntity.getContent();
                        String result = TextUtils.convertStreamToString(instream);           
                        instream.close();
                        // Try converting result to JSON
                        Log.e("FRIENDS", "Result: " + httpResponse);
                        try {
							ret = new JSONObject(result);
						} catch (JSONException e) {
							Log.e("FRIENDS", "Could not parse JSON.");
							ret = null;
						}
	                }
	                else
	                {
	                	Log.e("FRIENDS", "Response Entity Null.");
	                }
				}
				catch (IOException e)
				{}
		    	
				return ret;
			}
			@Override
			protected void onPostExecute(JSONObject result)
			{
				String msg = "Error occured.";		
				if (result != null)
				{
					String err;
					try
					{
						err = result.getString("error");
						msg = err;
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					try {
						err = result.getString("response");
						msg = err;
						// it was succesful
						doFetchAll(true);
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				// Put them all back as adapters
				//adaptLists();
				displayMessage(msg);
				mProgress.dismiss();
			}				
		};
		// Args needed for the working thread.
		String[] args = { mUserName, mPassword};
		t.execute(args);
	}
	public void displayMessage(String msg)
	{
		Log.e("FRIENDS", msg);
		UIUtils.showToast(this, msg);
	}
	class Friend
	{
		public long uid;
		public int status;
		public String username;
		Friend(JSONObject json)
		{
			try
			{
				uid = json.getLong("uid");
				status = json.getInt("status");
				username = json.getString("username");
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}